﻿/*******************************************************************************************************************************************
Modification History:
********************************************************************************************************************************************
Date		Author		    Description
********************************************************************************************************************************************
05/07/2011	Brian Kuhn	    Created IServiceBus interface
*******************************************************************************************************************************************/
using System;
using System.Xml;

namespace Concise
{
    /// <summary>
    /// Describes a node in an event-driven messaging engine that provides a means of sending and receiving messages between distributed systems.
    /// </summary>
    public interface IServiceBus : IDisposable
    {
        //=======================================================================================================
        //  Events
        //=======================================================================================================
        #region MessageReceived
        /// <summary>
        /// Occurs when a message is received.
        /// </summary>
        /// <remarks>
        /// This event is raised each time a message is sent from the message bus to the node.
        /// </remarks>
        event EventHandler<MessageReceivedEventArgs> MessageReceived;
        #endregion

        #region SubscriptionChanged
        /// <summary>
        /// Occurs when a message is received.
        /// </summary>
        /// <remarks>
        /// This event is raised each time there is a change in the subscriptions maintained by the message bus for the node.
        /// </remarks>
        event EventHandler<SubscriptionChangedEventArgs> SubscriptionChanged;
        #endregion

        //=======================================================================================================
        //  Properties
        //=======================================================================================================
        #region Endpoint
        /// <summary>
        /// The endpoint address of the content-based publish/subscribe message bus.
        /// </summary>
        /// <value>
        /// A <see cref="Uri"/> that represents the unique network address of the content-based publish/subscribe message bus.
        /// </value>
        Uri Endpoint
        {
            get;
        }
        #endregion

        #region SubscriberId
        /// <summary>
        /// Gets the unique identifier of the service bus node.
        /// </summary>
        /// <value>
        /// A <see cref="UniqueId"/> that identifies the service bus node.
        /// </value>
        UniqueId SubscriberId
        {
            get;
        }
        #endregion

        //=======================================================================================================
        //  Methods
        //=======================================================================================================
        #region Publish(params object[] messages)
        /// <summary>
        /// Publishes the specified <paramref name="messages"/>.
        /// </summary>
        /// <param name="messages">An <see cref="Array"/> of type <see cref="Object"/> that contains the  messages to publish.</param>
        /// <remarks>
        /// Calling <see cref="Publish"/> will transmit the specified <paramref name="messages"/> to the message bus, 
        /// which will match the messages against a set of subscribers based on message type and then forward each 
        /// message to the appropriate service bus nodes.
        /// </remarks>
        /// <exception cref="ArgumentNullException">The <paramref name="messages"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        void Publish(params object[] messages);
        #endregion

        #region Send(UniqueId destination, params object[] messages)
        /// <summary>
        /// Sends the supplied <paramref name="messages"/> to the specified <paramref name="destination"/>.
        /// </summary>
        /// <param name="destination">The unique identifier of the service bus node to send the <paramref name="messages"/> to.</param>
        /// <param name="messages">An <see cref="Array"/> of type <see cref="Object"/> that contains the messages to send.</param>
        /// <remarks>
        /// Calling <see cref="Send"/> will transmit the supplied <paramref name="messages"/> to the message bus, which will 
        /// forward the messages to the service bus node that matches the specified <paramref name="destination"/> identifier.
        /// </remarks>
        /// <exception cref="ArgumentNullException">The <paramref name="destination"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        /// <exception cref="ArgumentNullException">The <paramref name="messages"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        void Send(UniqueId destination, params object[] messages);
        #endregion

        #region Subscribe<TMessage>()
        /// <summary>
        /// Subscribes to messages of type <typeparamref name="TMessage"/>.
        /// </summary>
        /// <typeparam name="TMessage">The type of message to subscribe to.</typeparam>
        /// <returns>
        /// The <see cref="IServiceBus"/> object that this method was called on.
        /// </returns>
        IServiceBus Subscribe<TMessage>();
        #endregion

        #region Subscribe<TMessage>(Action<TMessage, IMessageContext> callback)
        /// <summary>
        /// Subscribes to messages of type <typeparamref name="TMessage"/>.
        /// </summary>
        /// <typeparam name="TMessage">The type of message to subscribe to.</typeparam>
        /// <param name="callback">The <see langword="delegate"/> method to execute when a message of type <typeparamref name="TMessage"/> is received.</param>
        /// <returns>
        /// The <see cref="IServiceBus"/> object that this method was called on.
        /// </returns>
        /// <exception cref="ArgumentNullException">The <paramref name="callback"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        IServiceBus Subscribe<TMessage>(Action<TMessage, IMessageContext> callback);
        #endregion

        #region Subscribe<TMessage>(Action<TMessage, IMessageContext> callback, ISpecification<TMessage> criteria)
        /// <summary>
        /// Subscribes to messages of type <typeparamref name="TMessage"/>.
        /// </summary>
        /// <typeparam name="TMessage">The type of message to subscribe to.</typeparam>
        /// <param name="callback">The <see langword="delegate"/> method to execute when a message of type <typeparamref name="TMessage"/> is received.</param>
        /// <param name="criteria">
        /// A <see cref="ISpecification{TMessage}"/> that defines the set of criteria a message of type <typeparamref name="TMessage"/> 
        /// must meet for the <paramref name="callback"/> to be invoked.
        /// </param>
        /// <returns>
        /// The <see cref="IServiceBus"/> object that this method was called on.
        /// </returns>
        /// <exception cref="ArgumentNullException">The <paramref name="callback"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        /// <exception cref="ArgumentNullException">The <paramref name="criteria"/> is a <see langword="null"/> reference (Nothing in Visual Basic).</exception>
        IServiceBus Subscribe<TMessage>(Action<TMessage, IMessageContext> callback, ISpecification<TMessage> criteria);
        #endregion

        #region Unsubscribe()
        /// <summary>
        /// Unubscribes from all message types.
        /// </summary>
        /// <returns>
        /// The <see cref="IServiceBus"/> object that this method was called on.
        /// </returns>
        IServiceBus Unsubscribe();
        #endregion

        #region Unsubscribe<TMessage>()
        /// <summary>
        /// Unsubscribes from messages of type <typeparamref name="TMessage"/>.
        /// </summary>
        /// <typeparam name="TMessage">The type of message to unsubscribe from.</typeparam>
        /// <returns>
        /// The <see cref="IServiceBus"/> object that this method was called on.
        /// </returns>
        IServiceBus Unsubscribe<TMessage>();
        #endregion
    }
}
